/*
 * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <inttypes.h>
#include "esp_log.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/timers.h"


#include "esp_wifi.h"
#include "nvs_flash.h"
#include <sys/socket.h>

#include "esp_mac.h"
#include "esp_bridge.h"
#include "esp_mesh_lite.h"

#include "BSP.h"
#include "Wireless.h"
#include "ModbusRtuSlave.h"
#include "Sensor.h"
#include "Display.h"




/*
*********************************************************************************************************
*                                 任务优先级，数值越大优先级越高
*********************************************************************************************************
*/
#define  APP_CFG_TASK_START_PRIO                        8
#define  APP_CFG_TASK_RTU_SLAVE_PRIO                    7
#define  APP_CFG_TASK_WIRELESS_PRIO                     6
#define  APP_CFG_TASK_SENSOR_PRIO                       5

/*
*********************************************************************************************************
*                                    任务栈大小，单位字节
*********************************************************************************************************
*/
#define  APP_CFG_TASK_START_STK_SIZE                    4096
#define  APP_CFG_TASK_RTU_SLAVE_STK_SIZE                4096
#define  APP_CFG_TASK_WIRELESS_STK_SIZE                 4096
#define  APP_CFG_TASK_SENSOR_STK_SIZE                   4096

/*
*********************************************************************************************************
*                                       静态全局变量
*********************************************************************************************************
*/ 
static TimerHandle_t Timer1;                        //用于统计系统运行时间  
EventGroupHandle_t SysEvent;				        //系统事件                      


// static char TaskInfo[2048];



extern  const char *TAG ;
/*	系统参数	*/
extern SystemParameter SysParam;
/*	系统状态	*/
extern SystemState SysState;



static void  AppTaskStart (void *arg);
static void  AppTaskRtuSlave (void *arg);
static void  AppTaskWireless (void *arg);
static void  AppTaskSensor (void *arg);




/**
  * @brief 定时器2超时处理函数（用于统计系统运行时间）
  * @param  None
  * @retval None
  */
static void Timer1_Process(TimerHandle_t timer)
{
	SysState.SysRunTime++;
}



/**
 * @brief Timed printing system information
 */
// static void print_system_info_timercb(TimerHandle_t timer)
// {
//     uint8_t primary                 = 0;
//     uint8_t sta_mac[6]              = {0};
//     wifi_ap_record_t ap_info        = {0};
//     wifi_second_chan_t second       = 0;
//     wifi_sta_list_t wifi_sta_list   = {0x0};

//     if (esp_mesh_lite_get_level() > 1) {
//         esp_wifi_sta_get_ap_info(&ap_info);
//     }
//     esp_wifi_get_mac(ESP_IF_WIFI_STA, sta_mac);
//     esp_wifi_ap_get_sta_list(&wifi_sta_list);
//     esp_wifi_get_channel(&primary, &second);

//     ESP_LOGI(TAG, "System information, channel: %d, layer: %d, self mac: " MACSTR ", parent bssid: " MACSTR
//              ", parent rssi: %d, free heap: %"PRIu32"", primary,
//              esp_mesh_lite_get_level(), MAC2STR(sta_mac), MAC2STR(ap_info.bssid),
//              (ap_info.rssi != 0 ? ap_info.rssi : -120), esp_get_free_heap_size());

//     for (int i = 0; i < wifi_sta_list.num; i++) {
//         ESP_LOGI(TAG, "Child mac: " MACSTR, MAC2STR(wifi_sta_list.sta[i].mac));
//     }

//     uint32_t size = 0;
//     const node_info_list_t *node = esp_mesh_lite_get_nodes_list(&size);
//     printf("MeshLite nodes %ld:\r\n", size);
//     for (uint32_t loop = 0; (loop < size) && (node != NULL); loop++) {
//         struct in_addr ip_struct;
//         ip_struct.s_addr = node->node->ip_addr;
//         printf("%ld: %d, "MACSTR", %s\r\n" , loop + 1, node->node->level, MAC2STR(node->node->mac_addr), inet_ntoa(ip_struct));
//         node = node->next;
//     }
// }

static esp_err_t esp_storage_init(void)
{
    esp_err_t ret = nvs_flash_init();

    if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
        // NVS partition was truncated and needs to be erased
        // Retry nvs_flash_init
        ESP_ERROR_CHECK(nvs_flash_erase());
        ret = nvs_flash_init();
    }

    return ret;
}





void app_main()
{
    // Set the log level for serial port printing.
    esp_log_level_set("*", ESP_LOG_INFO);

    esp_storage_init();
    
    BSP_Init( );		//初始化系统功能外设  

    xTaskCreate(AppTaskStart, "App Task Start", APP_CFG_TASK_START_STK_SIZE, NULL, APP_CFG_TASK_START_PRIO, NULL);
    

    // vTaskDelay( 10000 / portTICK_PERIOD_MS );

    // TimerHandle_t timer = xTimerCreate("print_system_info", 10000 / portTICK_PERIOD_MS,
    //                                    true, NULL, print_system_info_timercb);
    // xTimerStart(timer, 0);

    


    while( 1 )
    {
        vTaskDelay( 10 / portTICK_PERIOD_MS );

        LedCtrl(  );                //控制Led指示灯

        ReadChipTemp( );            //获取芯片的温度

        DisplayTempHumidity(  );    //显示温度、湿度

        SysParamSave(  );           //保存参数信息

        SysResetProcess( );         //系统复位处理

        // vTaskList(TaskInfo);	
        // ESP_LOGI(TAG, "\r\n");
        // ESP_LOGI(TAG, "task:");
        // ESP_LOGI(TAG, "%s\r\n",TaskInfo);
        // ESP_LOGI(TAG, "\r\n");
        
    }
}





/**
  * @brief  启动任务
  * @param  arg: Not used
  * @retval None
  */
static void  AppTaskStart (void *arg)
{
    /**************创建事件*********************/
	/**************系统事件*********************/					
	SysEvent = xEventGroupCreate();


    /**************创建定时器*********************/
    /**************用于统计系统运行时间*********************/	
    Timer1 = xTimerCreate("Timer Run Time", 1000 / portTICK_PERIOD_MS,
                                       true, NULL, Timer1_Process);

    xTimerStart(Timer1, 0);

    /**************创建任务*********************/
    /**************创建ModbusRtuSlave任务*********************/
    xTaskCreate(AppTaskRtuSlave, "App Task Modbus Rtu", APP_CFG_TASK_RTU_SLAVE_STK_SIZE, NULL, APP_CFG_TASK_RTU_SLAVE_PRIO, NULL);
    vTaskDelay( 300 / portTICK_PERIOD_MS );

    /**************创建无线通信任务*********************/
    if( SysParam.WorkParam.WorkMode != RS485)
    {
        xTaskCreate(AppTaskWireless, "App Task Wireless", APP_CFG_TASK_WIRELESS_STK_SIZE, NULL, APP_CFG_TASK_WIRELESS_PRIO, NULL);
        vTaskDelay( 300 / portTICK_PERIOD_MS );
    }

    /**************创建温湿度采集任务*********************/
    xTaskCreate(AppTaskSensor, "App Task Sensor", APP_CFG_TASK_SENSOR_STK_SIZE, NULL, APP_CFG_TASK_SENSOR_PRIO, NULL);
    vTaskDelay( 300 / portTICK_PERIOD_MS );


    while( 1 )
    {
        vTaskDelay( 10 / portTICK_PERIOD_MS );
    }
}



/**
  * @brief  ModbusRtuSlave任务
  * @param  arg: Not used
  * @retval None
  */
static void  AppTaskRtuSlave (void *arg)
{
    ModbusRtuSlaveInit( );         //初始化ModbusRtu从机

    while( 1 )
    {
        ModbusRtuSlaveProcess(  );  //Modbus Rtu从机数据处理
    }
}




/**
  * @brief  无线通信任务
  * @param  arg: Not used
  * @retval None
  */
static void  AppTaskWireless (void *arg)
{
    WirelessInit(  );           //初始化无线通信

    while( 1 )
    {
        WirelessProcess(  );    //无线通信处理
    }
}




/**
  * @brief  温湿度采集任务
  * @param  arg: Not used
  * @retval None
  */
static void  AppTaskSensor (void *arg)
{
    while( 1 )
    {
        SensorProcess( );       //处理传感器相关事项
    }
}






